<?php
namespace App\Http\Controller;

use App\Exception\SocketClientException;
use App\Lib\RpcClient\RpcClient;
use App\Lib\RpcClient\RpcResult;
use App\Lib\RpcRequest\RpcRequest;
use App\Model\Entity\AccountEntity;
use Exception;
use http\Env\Url;
use Swoft\Bean\BeanFactory;
use Swoft\Db\DB;
use Swoft\Db\Exception\DbException;
use Swoft\Http\Message\ContentType;
use Swoft\Http\Message\Request;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\Middleware;
use Swoft\Http\Server\Annotation\Mapping\Middlewares;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use Swoft\Log\Helper\CLog;
use Swoft\Stdlib\Helper\Arr;
use Swoft\Stdlib\Helper\JsonHelper;
use Swoft\Validator\Annotation\Mapping\Validate;
use Swoft\Http\Server\Annotation\Mapping\RequestMethod;
use Swoft\Http\Message\Response;
use App\Http\Middleware\TokenMiddleware\ExpiredToken;
use App\Http\Middleware\TokenMiddleware\ValidateToken;


/**
 * Class ClientController
 * @package App\Http\Controller
 * @Controller()
 */
class ClientController
{

    /**
     * @RequestMapping(route="/{tenant}")
     * @Middlewares(
     *     @Middleware(name="BlackListMiddleware"),
     *     @Middleware(name="MaintenanceMiddleware"),
     *     @Middleware(name="OverfrequencyMiddleware"),
     *     @Middleware(name="TenantMiddleware"),
     *     @Middleware(name="ServicesMiddleware"),
     *     @Middleware(name="ExpiredToken"),
     *     @Middleware(name="ValidateToken"),
     *     @Middleware(name="PermissionMiddleware"),
     *     @Middleware(name="LimiterMiddleware"),
     *     @Middleware(name="ApiCatchMiddleware")
     * )
     * @param Request $request
     * @return Response
     * @throws Exception
     */
    public function index(Request $request) {
        /** @var Service $service */
        $service = $request->getAttribute('service');
        /** @var ServiceInfo $serviceInfo */
        $serviceInfo = $request->getAttribute('serviceInfo');
        $tenant = $request->getAttribute('tenant');
        // 目标服务host信息
        $host = $service->getHost();
        $data = $request->input();
        // 添加租户信息
        $data['tenant'] = $tenant;
        //登录信息 用户-用户身份
        $request->getAttribute('uid')?$data['user_item_id'] = $request->getAttribute('uid'):'';
        $request->getAttribute('type')?$data['identity_id'] = $request->getAttribute('type'):'';
        $request->getAttribute('unionId')?$data['union_id'] = $request->getAttribute('unionId'):'';
        $data['remote_addr'] = $request->getHeader('x-forwarded-for')??(context()->getRequest()->getServerParams()['remote_addr']??'');
        $data['x_rpc'] = $data;

        try {
            /** @var RpcRequest $RpcRequest */
            $RpcRequest = BeanFactory::getBean(RpcRequest::class);
            $RpcRequest = $RpcRequest->getServiceByServiceInfo($data['service'])->setParams($data);
            CLog::info("###request:id---".uuid()."---time:".date('Y-m-d H:i:s')."---host：".$RpcRequest->getHost().'---data:'.json_encode($data));
            //@end 请求参数
            $data = $RpcRequest->query();
//            $data = RpcRequest(
//                $host,
//                $service->getNamespace() . "\\" . $serviceInfo->getServer(), $serviceInfo->getAction(),
//                $data);

//            if(!isset($data['result']) || !$data['result']){
//                unset($data['result']);
//            }

        } catch (Exception $e) {
            throw new SocketClientException();
        }
        return $data;
    }

    /**
     * @RequestMapping(route="/{tenant}/{service}/notify")
     * @Middlewares(
     *     @Middleware(name="BlackListMiddleware"),
     *     @Middleware(name="MaintenanceMiddleware"),
     *     @Middleware(name="TenantMiddleware"),
     *     @Middleware(name="NotifyServiceMiddleware"),
     *     @Middleware(name="LimiterMiddleware")
     * )
     * @param Request $request
     * @return mixed
     * @throws SocketClientException
     */
    public function notify(Request $request){
        /** @var Service $service */
        $service = $request->getAttribute('service');
        /** @var ServiceInfo $serviceInfo */
        $serviceInfo = $request->getAttribute('serviceInfo');
        $tenant = $request->getAttribute('tenant');
        // 目标服务host信息
        $host = $service->getHost();
        $data = $request->input();

        $sendData['params'] = $data??[];

        // 添加租户信息
        $sendData['tenant'] = $tenant;
        //添加header和path信息
        $sendData['headers'] = $request->getHeaders();
        $sendData['path'] = $request->getUriPath();
        CLog::info("###notify:id---".uuid()."---time:".date('Y-m-d H:i:s')."---host：".$host.'---data:'.json_encode($sendData));
        try {
            /** @var RpcRequest $RpcRequest */
            $RpcRequest = BeanFactory::getBean(RpcRequest::class);
            //@end 请求参数
            $data = $RpcRequest->getServiceByServiceInfo(getService())->setParams($sendData)->query();
//            $data = RpcRequest(
//                $host,
//                $service->getNamespace() . "\\" . $serviceInfo->getServer(), $serviceInfo->getAction(),
//                $sendData);
        } catch (Exception $e) {
            throw new SocketClientException();
        }

        //这里做一下头文件定义做回调地址
        if ($data !== null  && is_string($data)) {
            return context()->getResponse()->withContentType('text/html')->withData($data);
        }

        return $data;
    }

    /**
     * @RequestMapping(route="/{tenant}/test")
     * @Middleware(name="TenantMiddleware")
     * @param Request $request
     * @return Response|\Swoft\Rpc\Server\Response|\Swoft\Task\Response
     * @throws DbException
     */
    public function test(Request $request) {
        $account = AccountEntity::find(1);
        return context()->getResponse()->withData($account->toArray());
    }

    /**
     * @RequestMapping(route="/{tenant}/migrate")
     * @param Request $request
     * @return string
     */
    public function migrate(string $tenant, Request $request){
        //类型
        $type = $request->input('type', 1);

        $db = env('APP_ENV', 'local').'_gateway_'.$tenant;

        switch($type)
        {
            case 2:
                //代表租户
                $tenant_up = config('service.tenant_up');
                $migrate_up = explode(',', $tenant_up);
                break;
            default:
                //代表是总后台
                //删除
                $admin_up = config('service.admin_up');
                $migrate_up = explode(',', $admin_up);
                break;
        }

        vdump($migrate_up);
//        $migrate_up = [
//            "Database\Migration\UserCarrier",
//            "Database\Migration\UserCaptain"
//        ];
        //$migrate_up
        foreach ($migrate_up as $v){
            $result = mMigrate('up', ['name' => $v, 'db' => $db]);
        }
        return $result;
    }

}
